package com.rndemo.rn.view.RecyclerView;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;

import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.common.MapBuilder;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.uimanager.LayoutShadowNode;
import com.facebook.react.uimanager.ListViewShadowNode;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ThemedReactContext;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.ViewGroupManager;
import com.facebook.react.uimanager.annotations.ReactProp;
import com.facebook.react.uimanager.events.EventDispatcher;
import com.rndemo.R;
import com.rndemo.rn.event.AddViewEvent;
import com.rndemo.rn.event.RefreshChildEvent;
import com.rndemo.rn.view.LayoutManager.ILayoutManager;
import com.rndemo.rn.view.LayoutManager.StaggeredGridLayoutManager;
import com.rndemo.rn.view.RnFrameLayout;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Administrator on 2018/5/21.
 * StaggeredGridLayoutManager 这种布局有问题
 */
@ReactModule(name = RnRecyclerViewManage.REACT_CLASS)
public class RnRecyclerViewManage extends ViewGroupManager<RecyclerView> {
    protected static final String REACT_CLASS = "RCTRecyclerView";
    private SparseArray<RnRecyclerViewAdapter.ViewHolder> mCacheViews = new SparseArray<>();
    private RnRecyclerViewAdapter mAdapter;
    private int maxRows = 30;
    private int dividerHeight;
    private boolean isPaddingLeft;
    private boolean isPaddingTop;
    private boolean isPaddingRight;
    private boolean isPaddingBottom;
    private ColorDrawable mDivider = new ColorDrawable();

    private List mData = new ArrayList();
    private EventDispatcher mEventDispatcher;

    @Override
    public String getName() {
        return REACT_CLASS;
    }

    @Override
    protected RecyclerView createViewInstance(ThemedReactContext reactContext) {
        mEventDispatcher = reactContext.getNativeModule(UIManagerModule.class).getEventDispatcher();
        RecyclerView recyclerView = new RnRecyclerView(reactContext);
        recyclerView.getRecycledViewPool().setMaxRecycledViews(0,30);
        recyclerView.setClipToPadding(false);
        recyclerView.setClipChildren(false);
        recyclerView.setVerticalScrollBarEnabled(true);
        recyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
        RecyclerView.LayoutManager layoutManager = new StaggeredGridLayoutManager(3,OrientationHelper.VERTICAL);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(mAdapter = new RnRecyclerViewAdapter(recyclerView));
        recyclerView.addItemDecoration(mItemDecoration);
        return recyclerView;
    }

    @Override
    public boolean needsCustomLayoutForChildren() {
        return true;
    }

    @ReactProp(name = "maxRows", defaultInt = 30)
    public void setMaxRows(RecyclerView parent, int max) {
        maxRows = max;
    }

    @ReactProp(name = "isPadding")
    public void isPadding(RecyclerView parent, ReadableArray read) {
        Log("isPadding: " + read);
        isPaddingLeft = read.getBoolean(0);
        isPaddingTop = read.getBoolean(1);
        isPaddingRight = read.getBoolean(2);
        isPaddingBottom = read.getBoolean(3);
        setDividers(parent, dividerHeight);
    }

    @ReactProp(name = "dividerHeight", defaultInt = 10)
    public void setDividerHeight(RecyclerView parent, int height) {
        Log("setDividerHeight: " + height);
        dividerHeight = (int) PixelUtil.toPixelFromDIP(height);
//        if (dividerHeight > 0) {
//            setDividers(parent, dividerHeight);
//        }
    }

    @ReactProp(name = "dividerColor", defaultInt = Color.TRANSPARENT, customType = "Color")
    public void setDivider(RecyclerView parent, int color) {
        Log("setDivider: " + color);
        mDivider.setColor(color);
//        if (dividerHeight > 0) {
//            setDividers(parent, dividerHeight);
//        }
    }

    private void setDividers(RecyclerView parent, int height) {
        dividerHeight = height;
        int left = parent.getPaddingLeft();
        int top = parent.getPaddingTop();
        int right = parent.getPaddingRight();
        int bottom = parent.getPaddingBottom();
        if (isPaddingLeft) {
            left = height/2;
        }
        if (isPaddingTop) {
            top = height/2;
        }
        if (isPaddingRight) {
            right = height/2;
        }
        if (isPaddingBottom) {
            bottom = height/2;
        }
        parent.setPadding(left, top, right, bottom);
    }

    @ReactProp(name = "selectorColor", defaultInt = Color.TRANSPARENT, customType = "Color")
    public void setSelector(RecyclerView parent, int color) {
        mAdapter.setSelector(color);
    }

    @ReactProp(name = "orientation", defaultInt = OrientationHelper.VERTICAL)
    public void setOrientation(RecyclerView parent, int orientation) {
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if(layoutManager instanceof ILayoutManager){
            ((ILayoutManager)layoutManager).setOrientation(orientation);
        }
    }

    @ReactProp(name = "data")
    public void setData(RecyclerView parent, ReadableArray read) {
        mData.clear();
        if (read == null) {
            return;
        } else {
            for (int i = 0; i < read.size(); i++) {
                mData.add(i);
            }
        }
//        Log("setData: " + read.size() + " mData：" + mData.size());
        notifyDataSetChanged(parent, -1);
    }

    public void notifyDataSetChanged(RecyclerView listView, int index) {
        if (index > -1) {
            mAdapter.notifyItemChanged(index);
        } else {
            mAdapter.notifyDataSetChanged();
        }
    }

    //==========================================
    @Override
    public void addView(RecyclerView parent, View child, int index) {
//        Log("addView: " + index);
        RnRecyclerViewAdapter.ViewHolder viewHolder = mCacheViews.get(index);
        if (viewHolder != null && viewHolder.itemView != null && viewHolder.itemView instanceof RnFrameLayout) {
            ((RnFrameLayout) viewHolder.itemView).addReactView(child);
//            notifyDataSetChanged(parent,index);
        } else {
            throw new RuntimeException("请查看外层是否加了View(不加style视为没加) CacheView=" + mCacheViews.size() + " index=" + index + " ViewGroup=" + viewHolder.itemView + " Parent=" + child.getParent());
        }
    }

    @Override
    public void removeViewAt(RecyclerView parent, int index) {
        Log("removeViewAt: " + index);
        notifyDataSetChanged(parent, index);
    }

    @Override
    public void removeAllViews(RecyclerView parent) {
        Log("removeAllViews: ");
        mData.clear();
        mCacheViews.clear();
        notifyDataSetChanged(parent, -1);
    }


    private RecyclerView.ItemDecoration mItemDecoration = new RecyclerView.ItemDecoration() {
        @Override
        public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
//            ILayoutManager layoutManager = (ILayoutManager) parent.getLayoutManager();
//            Integer i = (Integer) view.getTag(R.id.react_view_index_tag);

            int left=dividerHeight/2;
            int top = dividerHeight/2;
            int right=dividerHeight/2;
            int bottom=dividerHeight/2;
//            if(i!=null){
//                int h = i/(layoutManager.getSpanCount());//行 从0开始
//                int l = i%(layoutManager.getSpanCount());//列 从0开始
//                boolean isFirstH = h==0;
//                boolean isLastH = h == (mData.size()-1)/layoutManager.getSpanCount();
//                boolean isFirstL = l==0;
//                boolean isLastL = false;
//                if(mData.size()>=layoutManager.getSpanCount()){
//                    isLastL = l==layoutManager.getSpanCount()-1;
//                }else{
//                    isLastL = l==mData.size()-1;
//                }
//                if(layoutManager.getOrientation()==OrientationHelper.VERTICAL){
//                    if(isFirstH){
//                        top=dividerHeight;
//                    }
//                    if (isFirstL){
//                        left = dividerHeight;
//                    }
//                }else{
//                    if(isFirstH){
//                        left=dividerHeight;
//                    }
//                    if (isFirstL){
//                        top = dividerHeight;
//                    }
//                }
//            }
            outRect.set(left, top, right, bottom);
        }
        @Override
        public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
            if(true){//不画
                return;
            }
            if(parent.getChildCount()>0){
                View childAt = parent.getChildAt(0);
                if(childAt instanceof ViewGroup && ((ViewGroup)childAt).getChildCount()==0){
                    return;
                }
            }
            ILayoutManager layoutManager = (ILayoutManager) parent.getLayoutManager();
            if (layoutManager.getOrientation() == OrientationHelper.VERTICAL) {
                drawVertical(c, parent);
            } else {
                drawHorizontal(c, parent);
            }
        }
        private void drawVertical(Canvas c, RecyclerView parent) {
            final int left = parent.getPaddingLeft();
            final int right = parent.getWidth() - parent.getPaddingRight();
            final int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = parent.getChildAt(i);
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
                final int top = child.getBottom() + params.bottomMargin;
                final int bottom = top + dividerHeight;
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }

        private void drawHorizontal(Canvas c, RecyclerView parent) {
            final int top = parent.getPaddingTop();
            final int bottom = parent.getHeight() - parent.getPaddingBottom();
            final int childCount = parent.getChildCount();
            for (int i = 0; i < childCount; i++) {
                final View child = parent.getChildAt(i);
                final RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();
                final int left = child.getRight() + params.rightMargin;
                final int right = left + dividerHeight;
                mDivider.setBounds(left, top, right, bottom);
                mDivider.draw(c);
            }
        }
    };

    private class RnRecyclerViewAdapter extends RecyclerView.Adapter<RnRecyclerViewAdapter.ViewHolder> {
        private int selected = -1;
        private int selector;
        private WeakReference<RecyclerView> mRecyclerView;
        public RnRecyclerViewAdapter(RecyclerView recyclerView) {
            mRecyclerView = new WeakReference<RecyclerView>(recyclerView);
        }

        @Override
        public RnRecyclerViewAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            RnFrameLayout viewGroup = new RnFrameLayout(parent.getContext());
            viewGroup.setTag(R.id.react_view_id_tag, mCacheViews.size());
            ViewHolder viewHolder = new ViewHolder(viewGroup);
            mEventDispatcher.dispatchEvent(new AddViewEvent(parent.getId(), mCacheViews.size()));
            mCacheViews.put(mCacheViews.size(), viewHolder);
//            Log("onCreateViewHolder:" + viewHolder.getLayoutPosition());
            return viewHolder;
        }

        @Override
        public void onBindViewHolder(RnRecyclerViewAdapter.ViewHolder holder, int position) {
            View itemView = holder.getItemView();
            holder.itemView.setTag(R.id.react_view_index_tag,position);
            if (itemView != null) {
                if (position == selected) {
                    itemView.setSelected(true);
                } else {
                    itemView.setSelected(false);
                }
            }
            if(holder.isBinde){
                RecyclerView recyclerView = mRecyclerView.get();
                if(recyclerView!=null){
//                    Log("onBindViewHolder:" + position);
                    eventToRefresh(position, holder.itemView, recyclerView);
                }
            }else{
                holder.isBinde = true;
            }
        }
        @Override
        public int getItemCount() {
            return mData.size();
        }

        public void setSelected(int selected) {
            this.selected = selected;
        }

        public void setSelector(int selector) {
            this.selector = selector;
        }

        class ViewHolder extends RecyclerView.ViewHolder {
            private boolean isBinde=false;//第一次创建不让 走onBindViewHolder
            public ViewHolder(View itemView) {
                super(itemView);
            }
            private View getItemView() {
                return ((ViewGroup) itemView).getChildAt(0);
            }
        }
    }

    /**
     * 这里最好还是 new 个新的Event，因为发现不new 的话滑动过快会报错
     */
    private void eventToRefresh(int position, View convertView, ViewGroup parent) {
//        RefreshChildEvent event = (RefreshChildEvent) convertView.getTag(R.id.react_view_event_tag);
//        if (event == null) {
        RefreshChildEvent event = new RefreshChildEvent(parent.getId(), (int) convertView.getTag(R.id.react_view_id_tag), position);
//        } else {
//            event.newEvent(parent.getId(), (int) convertView.getTag(R.id.react_view_id_tag), position);
//        }
        mEventDispatcher.dispatchEvent(event);
//        convertView.setTag(R.id.react_view_event_tag, event);
    }

    //================== java 调 js
    @Override
    public Map<String, Object> getExportedCustomDirectEventTypeConstants() {
        return MapBuilder.<String, Object>builder()
                .put(AddViewEvent.NAME, MapBuilder.of("registrationName", "onRenderItem"))
                .put(RefreshChildEvent.NAME, MapBuilder.of("registrationName", "onRefresh"))
                .build();
    }

    private void Log(String str) {
        Log.e(REACT_CLASS, str);
    }


    //====================css
    @Override
    public LayoutShadowNode createShadowNodeInstance() {
        return new ListViewShadowNode();
    }

    @Override
    public Class<? extends LayoutShadowNode> getShadowNodeClass() {
        return ListViewShadowNode.class;
    }
}
